home *** CD-ROM | disk | FTP | other *** search
- //****************************************************************//
- // Filename: ARexxPort.cpp
- // Autor: Christian Taulien of Strange Intelligence
- // Purpose: Testprogram for the SIFC
- // Creation: 11. Mai 1998
- //****************************************************************//
-
- #include <stdio.h>
- #include <ctype.h>
-
- #include "SIFC_Strings.h"
- #include "global.h"
- #include "ARexxPort.h"
-
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <rexx/storage.h>
-
- #include <clib/exec_protos.h>
- #include <clib/rexxsyslib_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/alib_protos.h>
-
- ARexxPortC::ARexxPortC(char *arg_sPortName, struct ARexxCommand **arg_ppoCommands)
- /*S*/
- {
- TRACE("Entry");
- setCommandList(arg_ppoCommands);
- m_bPortInstalled = FALSE;
- m_bProcessing = FALSE;
- setupARexxHost(arg_sPortName);
- }
- /*E*/
- ARexxPortC::~ARexxPortC()
- /*S*/
- {
- TRACE("Entry");
- closeDownARexxHost();
- }
- /*E*/
-
- BOOL ARexxPortC::setupARexxHost(char *arg_sPortName)
- /*S*/
- {
- TRACE("Entry");
- // einen bereits geöffneten Port schließen.
- if (isOpen())
- {
- closeDownARexxHost();
- } // if
-
- // Nur mit gültigen Portnamen weitermachen.
- if (!arg_sPortName)
- {
- return FALSE;
- } // if
-
- // den Message Port erstellen
- m_poPort = CreateMsgPort();
- if (!m_poPort)
- {
- return FALSE;
- }
-
- m_poPort->mp_Node.ln_Pri = 0;
-
- // MultiTasking ausschalten
- Forbid();
-
- // Wenn dieser Port schon vorhanden ist, dann neue Extension anhängen
- int ext = 0;
- do
- {
- char temp[20];
- sprintf(temp, ".%d", ++ext);
- m_oPortName = arg_sPortName;
- m_oPortName+= (char *) temp;
- } while (FindPort(m_oPortName));
-
- // Jetzt den Portnamen eintragen
- m_poPort->mp_Node.ln_Name = m_oPortName;
- AddPort(m_poPort);
-
- // MultiTasking wieder anschalten
- Permit();
-
- // ReadArgs-Struktur erzeugen
- if (!(m_poRDArgs = (struct RDArgs *) AllocDosObject(DOS_RDARGS, NULL)))
- {
- RemPort(m_poPort);
- DeleteMsgPort(m_poPort);
- return FALSE;
- } // if
-
- m_poRDArgs->RDA_Flags = RDAF_NOPROMPT;
- m_bPortInstalled = TRUE;
- return TRUE;
- }
- /*E*/
- void ARexxPortC::closeDownARexxHost(void)
- /*S*/
- {
- TRACE("Entry");
- // Test, ob überhaub ein Port vorhanden ist.
- if (m_poPort)
- {
- // Port abmelden
- RemPort(m_poPort);
-
- // MsgPort leeren
- struct RexxMsg *rexxmsg;
- while (rexxmsg = (struct RexxMsg *) GetMsg(m_poPort))
- {
- replyRexxCommand(rexxmsg, -20, (LONG) "Host closing down", NULL);
- } // while
-
- DeleteMsgPort(m_poPort);
- m_poPort = NULL;
- } // if
-
- // Freigeben der ReadArgs-Struktur
- if (m_poRDArgs )
- {
- FreeDosObject(DOS_RDARGS, m_poRDArgs);
- m_poRDArgs = NULL;
- } // if
- m_bPortInstalled = FALSE;
- }
- /*E*/
- void ARexxPortC::replyRexxCommand(struct RexxMsg *arg_poRexxMsg, LONG arg_lPrimary, LONG arg_lSecondary, char *arg_sResult)
- /*S*/
- {
- TRACE("Entry");
- // Wenn Ergebnis gefordert...
- if (arg_poRexxMsg->rm_Action & RXFF_RESULT )
- {
- // Wenn primary=0, dann soll das Ergebnis in result2 abgelegt werden
- if (arg_lPrimary == 0)
- {
- // Wenn es ein Ergebnis gibt, dann in secondary den ArgString eintragen
- if (arg_sResult)
- {
- arg_lSecondary = (long) CreateArgstring(arg_sResult, strlen(arg_sResult));
- }
- else
- {
- arg_lSecondary = NULL;
- } // if
- }
- else
- {
- char buf[20];
- // Wenn primary>0 dann liegt eine fehlernummer vor
- if( arg_lPrimary > 0 )
- {
- sprintf(buf, "%ld", arg_lSecondary);
- arg_sResult = buf;
- }
- else
- {
- // Wenn primary<0 dann liegt in arg_lSecondary ein Fehlertext vor
- arg_lPrimary = -arg_lPrimary;
- arg_sResult = (char *) arg_lSecondary;
- } // if
-
- // RC2 mit dem Fehlertext füllen
- SetRexxVar((struct Message *) arg_poRexxMsg, "RC2", arg_sResult, strlen(arg_sResult) );
-
- // secondary wieder löschen
- arg_lSecondary = 0;
- } // if
- }
- else if (arg_lPrimary < 0)
- {
- // Bei negativer primary in positive primary wandeln
- arg_lPrimary = -arg_lPrimary;
- } // if
-
- // Result-Felder ausfüllen
- arg_poRexxMsg->rm_Result1 = arg_lPrimary;
- arg_poRexxMsg->rm_Result2 = arg_lSecondary;
-
- // Zurückschicken der Nachricht
- ReplyMsg((struct Message *) arg_poRexxMsg);
- }
- /*E*/
- BOOL ARexxPortC::processARexxCommand(void)
- /*S*/
- {
- BOOL error=FALSE;
- TRACE("Entry");
- m_bProcessing = TRUE;
-
- // solange eine Message am Port anliegt
- struct RexxMsg *oARexxMsg;
- while (!error && (oARexxMsg = (struct RexxMsg *) GetMsg(m_poPort)))
- {
- // wenn ein ARexx-Befehl vorliegt
- if (((oARexxMsg->rm_Action & RXCODEMASK) == RXCOMM) && ARG0(oARexxMsg))
- {
- error=doRXCommand(oARexxMsg);
- }
- else // Sonst einfach ReplyMsg
- {
- ReplyMsg((struct Message *) oARexxMsg);
- } // if
- } // while
-
- m_bProcessing = FALSE;
-
- return error;
- }
- /*E*/
- struct ARexxCommand *ARexxPortC::findARexxCommand(StringC &arg_roCmdName)
- /*S*/
- {
- TRACE("Entry");
- if (!m_ppoCommands)
- {
- return NULL;
- } // if
-
- // suche den ARexx-Befehl in der Liste
- struct ARexxCommand *poFound = NULL;
- for (int i=0;m_ppoCommands[i] && !poFound;i++)
- {
- if (arg_roCmdName == m_ppoCommands[i]->m_sName)
- {
- poFound = m_ppoCommands[i];
- } // if
- } // for
- return poFound;
- }
- /*E*/
- BOOL ARexxPortC::doRXCommand(struct RexxMsg *arg_poARexxMsg)
- /*S*/
- {
- TRACE("Entry");
- // Das 1. Argument im RexxMsg-Struktur Member Args[] ist der Befehl selbst
- char *sBef = arg_poARexxMsg->rm_Args[0];
-
- for (int i=0, c=sBef[0]; isalnum(c) || c=='_'; c=sBef[++i]);
- StringC oARexxCmd(sBef, i);
- StringC oArgs(((char*) sBef+i));
- oArgs.trimString();
- oArgs += '\n';
-
- struct ARexxCommand *poFound = findARexxCommand(oARexxCmd);
-
- // wenn ARexx-Befehl nicht gefunden
- if (!poFound)
- {
- replyRexxCommand(arg_poARexxMsg, 20, ERROR_NOT_IMPLEMENTED, NULL);
- return FALSE;
- } // if
-
- BOOL done=FALSE;
- long rc=20;
- long rc2=0;
- LONG alArgArray[16];
-
- // Wenn dieser Befehl Argumente annimmt
- if (poFound->m_sArgs)
- {
- m_poRDArgs->RDA_Source.CS_Buffer = oArgs;
- m_poRDArgs->RDA_Source.CS_Length = oArgs.getLength();
- m_poRDArgs->RDA_Source.CS_CurChr = 0;
- m_poRDArgs->RDA_DAList = NULL;
- m_poRDArgs->RDA_Buffer = NULL;
-
- // Argumenten-Array nullen
- memset(alArgArray, 0, sizeof(LONG)*16);
-
- // Argumente einlesen
- if (!ReadArgs(poFound->m_sArgs, &alArgArray[0], m_poRDArgs))
- {
- rc = 10;
- rc2 = IoErr();
- } // if
- } // if
-
- // Wenn noch alles ok
- StringC oResult;
- if (!rc2)
- {
- done = dispatchARexxCommand(poFound->m_ulCommandID, &alArgArray[0], rc, rc2, oResult);
- if (!oResult.isEmpty() && (rc==0) && (arg_poARexxMsg->rm_Action & RXFF_RESULT))
- {
- if (SetRexxVar((struct Message *) arg_poARexxMsg, "RESULT", oResult, oResult.getLength()))
- {
- rc = -10;
- rc2 = (long) "Unable to set ARexx variable";
- } // if
- } // if
- } // if
-
- replyRexxCommand(arg_poARexxMsg, rc, rc2, (char *) oResult);
-
- // benutzten Speicher freigeben
- FreeArgs(m_poRDArgs );
-
- return done;
- }
- /*E*/
- BOOL ARexxPortC::dispatchARexxCommand(ULONG arg_ulCmdID, LONG *arg_alArgArray, LONG &arg_rlRC, LONG &arg_rlRC2, StringC &roResult)
- /*S*/
- {
- BOOL done = FALSE;
- TRACE("Entry");
- roResult.emptyString();
- arg_rlRC = NULL;
- arg_rlRC2 = NULL;
-
- switch (arg_ulCmdID)
- {
- default:
- TRACE("nicht implementierter ARexx-Befehl");
- arg_rlRC = 20;
- arg_rlRC2 = ERROR_NOT_IMPLEMENTED;
- break;
- } // switch
- return done;
- }
- /*E*/
-
-
-